package org.finesys.common.quartz.config;

import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.quartz.QuartzProperties;
import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.util.Map;
import java.util.Properties;

/**
 * 用于在Spring Boot应用中动态调整Quartz Scheduler的配置
 */
@Configuration
@RequiredArgsConstructor
public class SchedulerConfig implements SchedulerFactoryBeanCustomizer {
    private final ApplicationContext applicationContext;
    private final QuartzProperties quartzProperties;

    @Override
    public void customize(SchedulerFactoryBean schedulerFactoryBean) {
        //使得Quartz作业可以利用Spring的依赖注入和AOP特性‌
        schedulerFactoryBean.setJobFactory(new AutowireCapableBeanJobFactory(this.applicationContext.getAutowireCapableBeanFactory()));
        // 将计划程序设置为等待正在运行的作业完成，然后再关闭
        schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(quartzProperties.isWaitForJobsToCompleteOnShutdown());
        //设置覆盖现有任务
        schedulerFactoryBean.setOverwriteExistingJobs(quartzProperties.isOverwriteExistingJobs());
        //启动延时时间，秒
        schedulerFactoryBean.setStartupDelay((int) quartzProperties.getStartupDelay().getSeconds());
        //是否自动启动
        schedulerFactoryBean.setAutoStartup(quartzProperties.isAutoStartup());
        //quartz参数
        if (!quartzProperties.getProperties().isEmpty()) {
            schedulerFactoryBean.setQuartzProperties(asProperties(quartzProperties.getProperties()));
        }
        //任务调度名称
        schedulerFactoryBean.setSchedulerName(quartzProperties.getSchedulerName());
        //设置上下文
        schedulerFactoryBean.setApplicationContext(applicationContext);
    }


    /**
     * 转换为properties对象
     */
    private Properties asProperties(Map<String, String> map) {
        Properties properties = new Properties();
        properties.putAll(map);
        return properties;
    }

}
